﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using BasePlatformCommon;

namespace BasePlatformCom
{
	public class ComMainControl : BaseDevice
	{
		public SerialComPort comPort = null;		// 主控关联的串口对象

		public bool enableTypeLog = true;			// 主控在线检测线程 - 日志打印开关

		public bool liveFlag = false;				// 主控在线标记, 用于Core的基本检测过程

		public string portName = "";				// 主控关联的串口名称

		public string status = "";					// 状态

		public string index = "";					// 主控编号

		public string version = "";					// 主控版本

		public string dviStatus = "0";				// DVI 状态：0x01-正常, 0x02-错误, 其他值-不支持

		public new int currentMainPort = ComMainPort.U;		// 主控当前所用的 U/D 口, 默认为 U
		public int activeMainPort = ComMainPort.Unknown;	// 主控当前活跃的 U/D 口, 默认为 Unknown

		public List<SubControlInfo> subControlInfoList_U = null;	// 主控连接的分控信息
		public List<SubControlInfo> subControlInfoList_D = null;	// 主控连接的分控信息

		public List<EquipmentInfo> equipmentInfoList_U = null;		// 主控连接的附属设备信息
		public List<EquipmentInfo> equipmentInfoList_D = null;		// 主控连接的附属设备信息

		/***********************************************************************/

		private Thread watchThread = null;			// 检测线程
		
		private bool watchThreadRunning = false;	// 检测线程运行标记

		public bool watchThreadSleeping = false;	// 检测线程睡眠标记

		private bool threadSafeExit = false;		// 检测线程安全退出标记

		private int watchPeriod = 0;				// 主控检测间隔

		private ComSubControl subCtrl = null;		// 分控对象

		private ComEquipment equCtrl = null;		// 附属设备对象

		/***********************************************************************/

		// 灯条错灯检测使能开关
		private bool portDetailEnable = false;

		// 灯具点检测使能开关
		private bool lampCheckEnable = false;

		// 使能标记 Receiver Control
		private bool receiverControlEnable = false;

		/***********************************************************************/

		// 处理上层命令相关变量
		private Queue<ComCommand> cmdQueue1;
		private Queue<ComCommand> cmdQueue2;
		private int currentCmdQueue = 1;

		private static ReaderWriterLockSlim rwLock1 = new ReaderWriterLockSlim();
		private static ReaderWriterLockSlim rwLock2 = new ReaderWriterLockSlim();

		/***********************************************************************/

		// 构造函数
		public ComMainControl()
		{
			subControlInfoList_U = new List<SubControlInfo>();
			subControlInfoList_D = new List<SubControlInfo>();

			equipmentInfoList_U = new List<EquipmentInfo>();
			equipmentInfoList_D = new List<EquipmentInfo>();

			subCtrl = new ComSubControl();
			equCtrl = new ComEquipment();

			cmdQueue1 = new Queue<ComCommand>();
			cmdQueue2 = new Queue<ComCommand>();
		}

		// 设置主控关联的串口
		public void setComPort(string portName)
		{
			if (comPort != null && comPort.Opened)
			{
				comPort.Close();
			}

			this.portName = portName;
			comPort = new SerialComPort();
			comPort.PortName = portName;
			comPort.BaudRate = 115200;
			comPort.Parity = 0;
			comPort.ByteSize = 8;
			comPort.StopBits = 2;
			comPort.ReadTimeout = 1000;

			comPort.Open();
		}

		// 移除主控关联的串口
		public void removeComPort()
		{
			if (comPort != null && comPort.Opened)
			{
				comPort.Close();
			}

			comPort = null;
			portName = "";
		}

		// 启动主控检测线程
		public void startWatch(bool isBackground)
		{
			if (watchThreadRunning == true)
			{
				stopWatch();
			}

			if (watchThread == null)
			{
				watchThread = new Thread(watchProcess);
				watchThread.IsBackground = isBackground;
				watchThreadRunning = true;
				watchThread.Start();
			}
		}

		// 停止主控检测线程
		public void stopWatch()
		{
			if (watchThreadRunning == true)
			{
				watchThreadRunning = false;
				while (threadSafeExit == false)		// todo
				{
					Thread.Sleep(10);
				}
			}
		}

		// 【主控在线检测】 - 线程方法
		public void watchProcess()
		{
			threadSafeExit = false;
			watchThreadSleeping = false;

			subCtrl.random = random;
			equCtrl.random = random;

			subControlInfoList_U.Clear();
			subControlInfoList_D.Clear();
			equipmentInfoList_U.Clear();
			equipmentInfoList_D.Clear();

			while (watchThreadRunning)
			{
				try
				{
					// 灯具检测过程中, 暂停主检测线程, 避免串口通信冲突
					if (lampCheckEnable == true)
					{
						watchThreadSleeping = true;
						Thread.Sleep(1000);
						continue;
					}
					else
					{
						watchThreadSleeping = false;
					}

					#region 检测主控自身信息

					// 通过读取主控版本, 检测主控是否在线
					version = detectMainControlVersion();

					if (version.Equals(""))
					{
						typeLog("[" + comPort.PortName + "]: 主控离线");
						liveFlag = false;
						break;
					}
					else
					{
						typeLog("[" + comPort.PortName + "]: 主控在线, 版本: " + version);
					}

					// 读取主控编号
					index = readMainControlIndex();
					typeLog("[" + comPort.PortName + "]: 主控编号: " + index);

					// 读取 DVI 状态
					dviStatus = readDviStatus();
					typeLog("[" + comPort.PortName + "]: 主控 DVI 状态: " + dviStatus);

					#endregion

					#region 检测主控端口 U 挂载的分控

					int currentDepth = 0;
					setCurrentMainPort(ComMainPort.U);

					while (currentDepth < 256)
					{
						currentDepth++;

						// 当前深度的分控已注册
						if (currentDepth <= subControlInfoList_U.Count)
						{
							string subVersion = subCtrl.detectSubControlVersion(comPort, currentMainPort, 0, currentDepth);

							// 如本次未检测到，执行一次额外的检测
							if (subVersion.Equals(""))
							{
								subVersion = subCtrl.detectSubControlVersion(comPort, currentMainPort, 0, currentDepth);
							}

							if (!subVersion.Equals(""))
							{
								// 当前深度的分控在线，继续检测
								//typeLog("[" + comPort.PortName + "]: subVersion = " + subVersion);

								// 复制分控返回信息 - 256 bytes
								Array.Copy(subCtrl.replyData, subControlInfoList_U[currentDepth - 1].replyData, 256);

								// 设置箱体监控卡检测结果、crc_err_count、package_count
								subControlInfoList_U[currentDepth - 1].hasWatchCard = subCtrl.hasWatchCard;
								subControlInfoList_U[currentDepth - 1].crc_err_count = subCtrl.crc_err_count;
								subControlInfoList_U[currentDepth - 1].package_count = subCtrl.package_count;

								// 当前分控连接了箱体监控卡
								if (subCtrl.hasWatchCard)
								{
									subControlInfoList_U[currentDepth - 1].setWatchCardInfoBytes(subCtrl.watchCardInfoBytes);
								}

								#region 【可选】灯条错灯检测

								if (portDetailEnable == true)
								{
									if (receiverControlEnable == false)
									{
										enableReceiverControl();
									}

									// 更新分控灯具端口信息 px_total、px_err
									subControlInfoList_U[currentDepth - 1].setPortInfo(subCtrl.p_total, subCtrl.p_err);

									for (int portIndex = 1; portIndex <= 8; portIndex++)
									{
										byte[] lightDetailBytes = subCtrl.detectLightDetailBytes(comPort, ComMainPort.U, 0, currentDepth, portIndex);
										subControlInfoList_U[currentDepth - 1].setLightDetailBytes(portIndex, lightDetailBytes);
									}
								}
								else
								{
									if (receiverControlEnable == true)
									{
										disableReceiverControl();
									}
								}

								#endregion

								continue;
							}
							else
							{
								// 当前深度的分控已离线，移除当前和后继分控的注册信息
								for (int k = subControlInfoList_U.Count - 1; k >= currentDepth - 1; k--)
								{
									subControlInfoList_U.RemoveAt(k);
								}
								break;
							}
						}
						// 当前深度的分控未注册
						else
						{
							string subVersion_new = subCtrl.detectSubControlVersion(comPort, currentMainPort, 0, currentDepth);
							if (!subVersion_new.Equals(""))
							{
								// 发现新级联深度的分控在线，添加注册信息
								//typeLog("[" + comPort.PortName + "]: subVersion_new = " + subVersion_new);

								SubControlInfo subCtrlInfo = new SubControlInfo();
								subCtrlInfo.index = currentDepth;
								subCtrlInfo.version = subVersion_new;
								subCtrlInfo.setPortInfo(subCtrl.p_total, subCtrl.p_err);
								subCtrlInfo.setWatchCardInfoBytes(subCtrl.watchCardInfoBytes);
								subControlInfoList_U.Add(subCtrlInfo);
								
								activeMainPort = ComMainPort.U;

								continue;
							}
							else
							{
								break;
							}
						}
					}

					#endregion

					#region 检测主控端口 D 挂载的分控

					currentDepth = 0;
					setCurrentMainPort(ComMainPort.D);

					while (currentDepth < 256)
					{
						currentDepth++;

						// 当前深度的分控已注册
						if (currentDepth <= subControlInfoList_D.Count)
						{
							string subVersion = subCtrl.detectSubControlVersion(comPort, currentMainPort, 0, currentDepth);

							// 如本次未检测到，执行一次额外的检测
							if (subVersion.Equals(""))
							{
								subVersion = subCtrl.detectSubControlVersion(comPort, currentMainPort, 0, currentDepth);
							}

							if (!subVersion.Equals(""))
							{
								// 当前深度的分控在线，继续检测
								//typeLog("[" + comPort.PortName + "]: subVersion = " + subVersion);

								// 复制分控返回信息 - 256 bytes
								Array.Copy(subCtrl.replyData, subControlInfoList_D[currentDepth - 1].replyData, 256);

								// 设置箱体监控卡检测结果、crc_err_count、package_count
								subControlInfoList_D[currentDepth - 1].hasWatchCard = subCtrl.hasWatchCard;
								subControlInfoList_D[currentDepth - 1].crc_err_count = subCtrl.crc_err_count;
								subControlInfoList_D[currentDepth - 1].package_count = subCtrl.package_count;

								// 当前分控连接了箱体监控卡
								if (subCtrl.hasWatchCard)
								{
									subControlInfoList_D[currentDepth - 1].setWatchCardInfoBytes(subCtrl.watchCardInfoBytes);
								}

								#region 【可选】灯条错灯检测

								if (portDetailEnable == true)
								{
									if (receiverControlEnable == false)
									{
										enableReceiverControl();
									}

									// 更新分控灯具端口信息 px_total、px_err
									subControlInfoList_D[currentDepth - 1].setPortInfo(subCtrl.p_total, subCtrl.p_err);

									for (int portIndex = 1; portIndex <= 8; portIndex++)
									{
										byte[] lightDetailBytes = subCtrl.detectLightDetailBytes(comPort, ComMainPort.D, 0, currentDepth, portIndex);
										subControlInfoList_D[currentDepth - 1].setLightDetailBytes(portIndex, lightDetailBytes);
									}
								}
								else
								{
									if (receiverControlEnable == true)
									{
										disableReceiverControl();
									}
								}

								#endregion

								continue;
							}
							else
							{
								// 当前深度的分控已离线，移除当前和后继分控的注册信息
								for (int k = subControlInfoList_D.Count - 1; k >= currentDepth - 1; k--)
								{
									subControlInfoList_D.RemoveAt(k);
								}
								break;
							}
						}
						// 当前深度的分控未注册
						else
						{
							string subVersion_new = subCtrl.detectSubControlVersion(comPort, currentMainPort, 0, currentDepth);
							
							if (!subVersion_new.Equals(""))
							{
								// 发现新级联深度的分控在线，添加注册信息
								//typeLog("[" + comPort.PortName + "]: subVersion_new = " + subVersion_new);

								SubControlInfo subCtrlInfo = new SubControlInfo();
								subCtrlInfo.index = currentDepth;
								subCtrlInfo.version = subVersion_new;
								subCtrlInfo.setPortInfo(subCtrl.p_total, subCtrl.p_err);
								subCtrlInfo.setWatchCardInfoBytes(subCtrl.watchCardInfoBytes);

								subControlInfoList_D.Add(subCtrlInfo);

								activeMainPort = ComMainPort.D;

								continue;
							}
							else
							{
								break;
							}
						}
					}

					#endregion

					typeLog("[" + comPort.PortName + "]: 主控端口 U 连接的分控数量：" + subControlInfoList_U.Count);
					typeLog("[" + comPort.PortName + "]: 主控端口 D 连接的分控数量：" + subControlInfoList_D.Count);

					#region 检测主控端口 U 挂载的附属设备

					currentDepth = 0;
					setCurrentMainPort(ComMainPort.U);

					while (currentDepth < 256)
					{
						currentDepth++;

						if (currentDepth <= equipmentInfoList_U.Count)
						{
							// 当前深度的附属设备已注册
							string equVersion = equCtrl.detectEqupmentVersion(comPort, currentMainPort, 0, currentDepth);

							if (!equVersion.Equals(""))
							{
								// 当前深度的附属设备在线，继续检测
								//typeLog("[" + comPort.PortName + "]: equVersion = " + equVersion);

								// 设置环境监测器 Lux 值、Bright 值
								equipmentInfoList_U[currentDepth - 1].luxValue = equCtrl.luxValue;
								equipmentInfoList_U[currentDepth - 1].brightValue = equCtrl.brightValue;

								continue;
							}
							else
							{
								// 当前深度的附属设备已离线，移除当前和后继附属设备的注册信息
								for (int k = equipmentInfoList_U.Count - 1; k >= currentDepth - 1; k--)
								{
									equipmentInfoList_U.RemoveAt(k);
								}
								break;
							}
						}
						else
						{
							string equVersion_new = equCtrl.detectEqupmentVersion(comPort, currentMainPort, 0, currentDepth);
							if (!equVersion_new.Equals(""))
							{
								// 发现新级联深度的附属设备在线，添加注册信息
								//typeLog("[" + comPort.PortName + "]: equVersion_new = " + equVersion_new);
								EquipmentInfo equipmentInfo = new EquipmentInfo();
								equipmentInfo.index = currentDepth;
								equipmentInfo.version = equVersion_new;
								equipmentInfoList_U.Add(equipmentInfo);
								activeMainPort = ComMainPort.U;
								continue;
							}
							else
							{
								break;
							}
						}
					}

					#endregion

					#region 检测主控端口 D 挂载的附属设备

					currentDepth = 0;
					setCurrentMainPort(ComMainPort.D);

					while (currentDepth < 256)
					{
						currentDepth++;

						if (currentDepth <= equipmentInfoList_D.Count)
						{
							// 当前深度的附属设备已注册
							string equVersion = equCtrl.detectEqupmentVersion(comPort, currentMainPort, 0, currentDepth);

							if (!equVersion.Equals(""))
							{
								// 当前深度的附属设备在线，继续检测
								//typeLog("[" + comPort.PortName + "]: equVersion = " + equVersion);

								// 设置环境监测器 Lux 值、Bright 值
								equipmentInfoList_D[currentDepth - 1].luxValue = equCtrl.luxValue;
								equipmentInfoList_D[currentDepth - 1].brightValue = equCtrl.brightValue;

								continue;
							}
							else
							{
								// 当前深度的附属设备已离线，移除当前和后继附属设备的注册信息
								for (int k = equipmentInfoList_D.Count - 1; k >= currentDepth - 1; k--)
								{
									equipmentInfoList_D.RemoveAt(k);
								}
								break;
							}
						}
						else
						{
							string equVersion_new = equCtrl.detectEqupmentVersion(comPort, currentMainPort, 0, currentDepth);
							if (!equVersion_new.Equals(""))
							{
								// 发现新级联深度的附属设备在线，添加注册信息
								//typeLog("[" + comPort.PortName + "]: equVersion_new = " + equVersion_new);
								EquipmentInfo equipmentInfo = new EquipmentInfo();
								equipmentInfo.index = currentDepth;
								equipmentInfo.version = equVersion_new;
								equipmentInfo.luxValue = equCtrl.luxValue;
								equipmentInfo.brightValue = equCtrl.brightValue;
								equipmentInfoList_D.Add(equipmentInfo);
								activeMainPort = ComMainPort.D;
								continue;
							}
							else
							{
								break;
							}
						}
					}

					#endregion

					typeLog("[" + comPort.PortName + "]: 主控端口 U 连接的附属设备数量：" + equipmentInfoList_U.Count);
					typeLog("[" + comPort.PortName + "]: 主控端口 D 连接的附属设备数量：" + equipmentInfoList_D.Count);

					#region 根据检测到的设备数量确定主控活跃的 U/D 口
					
					int deviceNum_U = subControlInfoList_U.Count + equipmentInfoList_U.Count;
					int deviceNum_D = subControlInfoList_D.Count + equipmentInfoList_D.Count;

					if (deviceNum_U > 0)
					{
						activeMainPort = ComMainPort.U;
					}
					else if (deviceNum_D > 0)
					{
						activeMainPort = ComMainPort.D;
					}
					else
					{
						activeMainPort = ComMainPort.Unknown;
					}
					
					#endregion

					#region 执行上层命令

					// 激活主控当前的 activeMainPort
					setCurrentMainPort(activeMainPort);

					// 执行上层命令
					executeUpLevelCommand();

					#endregion

					typeLog("-----------------------------------------------");

					Thread.Sleep(watchPeriod);
				}
				catch (Exception ex)
				{
					enableTypeLog = true;
					typeLog(ex.Message + ex.StackTrace);
					comPort.Close();
					liveFlag = false;
					break;
				}
			}

			// 循环后处理
			comPort.Close();
			watchThreadRunning = false;
			threadSafeExit = true;
		}

		// 读取主控（发送卡）编号
		private string readMainControlIndex()
		{
			int regData = 0;

			if (comPort == null)
			{
				return "";
			}

			readMainReg(comPort, 0x88, ref regData);

			if (ackIsOk == false)
			{
				return "";
			}
			else
			{
				return regData.ToString();
			}
		}

		// 检测主控（发送卡）版本
		public string detectMainControlVersion()
		{
			string version = "";

			if (comPort == null)
			{
				return "";
			}

			int regData = 0;

            for (int i = 0xF9; i <= 0xFF; i++)
			{
				readMainReg(comPort, i, ref regData);

				if (ackIsOk == false)
				{
					return "";
				}

				switch (i)
				{
					case 0xF9:
						if (regData < 10)
							version = "_X0" + regData;
						else
							version = "_X" + regData;
						break;
					case 0xFA:
						if (regData < 10)
							version = "0" + regData + version;
						else
							version = regData + version;
						break;
					case 0xFB:
						version = "_" + chr(regData) + version;
						break;
					case 0xFC:
						if (regData < 10)
							version = "0" + regData + version;
						else
							version = regData + version;
						break;
					case 0xFD:
						version = regData + version;
						break;
					case 0xFE:
						version = chr(regData) + version;
						break;
					case 0xFF:
						version = chr(regData) + version;
						break;
				}
			}

			return version;
		}

		// 读取主控 DVI 状态
		public string readDviStatus()
		{
			if (comPort == null)
			{
				return "0";
			}

			int regData = 0;
			
			readMainReg(comPort, 0xc0, ref regData);

			if (ackIsOk == false)
			{
				return "0";		// ack错误导致未正确读回值
			}
			else
			{
				if ((regData & 0x08) == 0)
				{
					return "2";	// 错误
				}
				else
				{
					return "1";	// 正确
				}
			}
		}

		// 读取主控当前使用的端口 U/D
		public int getMainCtrlActivePort()
		{
			return activeMainPort;
		}

		// 设置主控当前使用的端口 U/D
		public void setCurrentMainPort(int mainPort)
		{
			currentMainPort = mainPort;

			if (currentMainPort == ComMainPort.U)
			{
				if (comPort != null && !comPort.PortName.Equals(""))
				{
					writeMainReg(comPort, 0x45, 0x03);
				}
			}
			else if (currentMainPort == ComMainPort.D)
			{
				if (comPort != null && !comPort.PortName.Equals(""))
				{
					writeMainReg(comPort, 0x45, 0x05);
				}
			}
		}

		// 启用 Receiver Control
		public void enableReceiverControl()
		{
			if (comPort != null && receiverControlEnable == false)
			{
				byte[] memData = new byte[1024];
				for (int i = 0; i < 1024; i++)
				{
					memData[i] = 0;
				}

				readMainMem(comPort, 0x004C0200, memData);

				memData[1] = Convert.ToByte(memData[1] | 0x4);

				writeMainMem(comPort, 0x00000200, memData);

				receiverControlEnable = true;
			}
		}

		// 禁用 Receiver Control
		private void disableReceiverControl()
		{
			if (comPort != null && receiverControlEnable == true)
			{
				byte[] memData = new byte[1024];
				for (int i = 0; i < 1024; i++)
				{
					memData[i] = 0;
				}

				readMainMem(comPort, 0x004C0200, memData);

				memData[1] = Convert.ToByte(memData[1] | 0xFB);

				writeMainMem(comPort, 0x00000200, memData);

				receiverControlEnable = false;
			}
		}

		// 设置灯具巡检使能
		public void setLampCheckEnable(bool enable)
		{
			lampCheckEnable = enable;
		}

		#region 灯条错灯检测、灯具检测

		// 开启灯条错灯检测
		public void enablePortDetailDetect()
		{
			portDetailEnable = true;
		}

		// 禁止灯具检测
		public void disablePortDetailDetect()
		{
			portDetailEnable = false;
		}
		
		// 检测单个灯具
		public LampStatePara getLampStatePara(int subIndex, int subPortIndex, int miniIndex)
		{
			LampStatePara lampStatePara = new LampStatePara();
			
			lampStatePara.SubIndex = subIndex;
			lampStatePara.PortIndex = subPortIndex;
			lampStatePara.LampIndex = miniIndex;
			
			byte[] replyBytes = subCtrl.getLampStateBytes(comPort, currentMainPort, 0, subIndex, subPortIndex, miniIndex);
			if (replyBytes != null)
			{
				lampStatePara.PacketId = replyBytes[3];
				lampStatePara.LampAddr = replyBytes[4] | replyBytes[5] << 8;
				lampStatePara.PacketLength = replyBytes[6] | replyBytes[7] << 8;
				lampStatePara.DmxAddr = replyBytes[8] | replyBytes[9] << 8;
				lampStatePara.DmxId = replyBytes[10] | replyBytes[11] << 8;
				lampStatePara.Current = replyBytes[12] | replyBytes[13] << 8;
				lampStatePara.Voltage = replyBytes[14] | replyBytes[15] << 8;
				lampStatePara.Temperature = replyBytes[16] | replyBytes[17] << 8;
				lampStatePara.LampId = replyBytes[19] | replyBytes[20] << 8 | replyBytes[21] << 16 | replyBytes[22] << 24;
				lampStatePara.LampChannel = replyBytes[23] | replyBytes[24] << 8;
			}
			else
			{
				lampStatePara = null;
			}

			return lampStatePara;
		}
		
		#endregion

		#region 处理上层命令

		// 对外接口 - 接收上层命令
		public void addCommand(ComCommand cmd)
		{
			if (currentCmdQueue == 1)
			{
				try
				{
					rwLock1.EnterWriteLock();
					cmdQueue1.Enqueue(cmd);
				}
				finally
				{
					rwLock1.ExitWriteLock();
				}
			}
			else if (currentCmdQueue == 2)
			{
				try
				{
					rwLock2.EnterWriteLock();
					cmdQueue2.Enqueue(cmd);
				}
				finally
				{
					rwLock2.ExitWriteLock();
				}
			}
		}

		// 执行上层命令队列 - 双缓冲队列
		private void executeUpLevelCommand()
		{
			if (currentCmdQueue == 1)
			{
				try
				{
					rwLock2.EnterWriteLock();
					while (cmdQueue2.Count > 0)
					{
						ComCommand cmd = cmdQueue2.Dequeue();
						executeOneCommand(cmd);
					}
				}
				catch(Exception ex)
				{
					typeLog(ex.Message + ex.StackTrace);
				}
				finally
				{
					cmdQueue2.Clear();
					currentCmdQueue = 2;
					rwLock2.ExitWriteLock();
				}
			}
			else if (currentCmdQueue == 2)
			{
				try
				{
					rwLock1.EnterWriteLock();
					while (cmdQueue1.Count > 0)
					{
						ComCommand cmd = cmdQueue1.Dequeue();
						executeOneCommand(cmd);
					}
				}
				catch (Exception ex)
				{
					typeLog(ex.Message + ex.StackTrace);
				}
				finally
				{
					cmdQueue1.Clear();
					currentCmdQueue = 1;
					rwLock1.ExitWriteLock();
				}
			}
		}

		// 执行单条上层命令（主控实际执行）
		private void executeOneCommand(ComCommand cmd)
		{
			// 发给【主控】自身的命令
			if (cmd.target.Equals(CommandTarget.MainCtrl))
			{
				#region 【Coolux接口】设置亮度
				if (cmd.operType.Equals(CommandOperTpye.CooluxSetBright))
				{
					object param = null;
					cmd.paramDict.TryGetValue("BRIGH", out param);

					if (param != null)
					{
						string paramValue = (string)param;

						readMainMem(comPort, 0x004C0200, memData);

						memData[4] = mod256(Convert.ToInt32(paramValue));	// 修改整屏亮度

						writeMainMem(comPort, 0x00000200, memData);

						readMainMem(comPort, 0x00000200, memData);
					}
				}
				#endregion

				#region 【Coolux接口】设置对比度
				else if (cmd.operType.Equals(CommandOperTpye.CooluxSetContrast))
				{
					object param = null;
					cmd.paramDict.TryGetValue("CONTR", out param);

					if (param != null)
					{
						string paramValue = (string)param;

						readMainMem(comPort, 0x4C0200, memData);

						memData[3] = mod256(Convert.ToInt32(paramValue));	// 修改对比度

						writeMainMem(comPort, 0x0200, memData);

						readMainMem(comPort, 0x0200, memData);
					}
				}
				#endregion

				#region 【内部功能】设置亮度/对比度, 全局操作所有分控
				else if (cmd.operType.Equals(CommandOperTpye.SetBrightContrast))
				{
					object brightnessValue = null;
					cmd.paramDict.TryGetValue("brightness", out brightnessValue);
					object contrastValue = null;
					cmd.paramDict.TryGetValue("contrast", out contrastValue);
					object temperatureValue_r = null;
					cmd.paramDict.TryGetValue("temperature_r", out temperatureValue_r);
					object temperatureValue_g = null;
					cmd.paramDict.TryGetValue("temperature_g", out temperatureValue_g);
					object temperatureValue_b = null;
					cmd.paramDict.TryGetValue("temperature_b", out temperatureValue_b);

					if (brightnessValue != null && contrastValue != null && temperatureValue_r != null && temperatureValue_g != null && temperatureValue_b != null)
					{
						int brightness, contrast, temperature_r, temperature_g, temperature_b;

						brightness = Convert.ToInt32(brightnessValue);
						contrast = Convert.ToInt32(contrastValue);
						temperature_r = Convert.ToInt32(temperatureValue_r);
						temperature_g = Convert.ToInt32(temperatureValue_g);
						temperature_b = Convert.ToInt32(temperatureValue_b);

						byte[] configData = buildBrightContrastPacket(brightness, contrast, temperature_r, temperature_g, temperature_b);

						writeMainMem(comPort, 0x0200, configData);
					}
				}
				#endregion
			}

			// 通过【主控】操作下属【分控】的命令
			else if (cmd.target.Equals(CommandTarget.SubCtrl))
			{
				// 设置 MCU 显示参数
				if (cmd.operType.Equals(CommandOperTpye.SetMcuDispParameter))
				{
					object paramBrightTotal = null;
					cmd.paramDict.TryGetValue("brightTotal", out paramBrightTotal);
					object paramBrightR = null;
					cmd.paramDict.TryGetValue("brightR", out paramBrightR);
					object paramBrightG = null;
					cmd.paramDict.TryGetValue("brightG", out paramBrightG);
					object paramBrightB = null;
					cmd.paramDict.TryGetValue("brightB", out paramBrightB);
					object paramBrightW = null;
					cmd.paramDict.TryGetValue("brightW", out paramBrightW);
					object paramGamma = null;
					cmd.paramDict.TryGetValue("gamma", out paramGamma);

					if (paramBrightTotal != null && paramBrightR != null && paramBrightG != null && paramBrightB != null && paramBrightW != null && paramGamma != null)
					{
						byte[] cmdData = new byte[256];

						cmdData[2] = 0x65;
						cmdData[8] = Convert.ToByte(paramBrightTotal);	// 整体亮度
						cmdData[9] = Convert.ToByte(paramBrightR);		// 通道 R 亮度
						cmdData[10] = Convert.ToByte(paramBrightG);		// 通道 G 亮度
						cmdData[11] = Convert.ToByte(paramBrightB);		// 通道 B 亮度
						cmdData[12] = Convert.ToByte(paramBrightW);		// 通道 W 亮度
						cmdData[13] = Convert.ToByte(paramGamma);		// Gamma 值

						// 全局操作
						writeSubMem(comPort, currentMainPort, 0, 0x20A00000, cmdData);
					}
				}
			}

			// 通过【主控】操作下属【附属设备】的命令
			else if (cmd.target.Equals(CommandTarget.Equipment))
			{
				#region 环境监测器 设置 Lux-亮度、Gamma-亮度、其他参数（PWM_Level, Start_Gray, Low_Gray_Value, Sample_Time, Env_Light_En, Color_Restore_En）
				if (cmd.operType.Equals(CommandOperTpye.SetLuxGamma))
				{
					object luxBrightTableValue = null;
					cmd.paramDict.TryGetValue("luxBrightTable", out luxBrightTableValue);

					object gammaBrightTableValue = null;
					cmd.paramDict.TryGetValue("gammaBrightTable", out gammaBrightTableValue);

					object otherParaTableValue = null;
					cmd.paramDict.TryGetValue("otherParaTable", out otherParaTableValue);

					byte[] luxBrightTable = (byte[])luxBrightTableValue;
					byte[] gammaBrightTable = (byte[])gammaBrightTableValue;
					byte[] otherParaTable = (byte[])otherParaTableValue;

					if (luxBrightTable != null && gammaBrightTable != null && otherParaTable != null)
					{
						byte[] luxBrightTable_sub1 = new byte[256];
						byte[] luxBrightTable_sub2 = new byte[256];
						Array.Copy(luxBrightTable, 0, luxBrightTable_sub1, 0, 256);
						Array.Copy(luxBrightTable, 256, luxBrightTable_sub2, 0, 256);

						writeEquMem(comPort, activeMainPort, 1, 0x4c5000, luxBrightTable_sub1);
						writeEquMem(comPort, activeMainPort, 1, 0x4c5100, luxBrightTable_sub2);
						writeEquMem(comPort, activeMainPort, 1, 0x4c5200, gammaBrightTable);
						writeEquMem(comPort, activeMainPort, 1, 0x4c5300, otherParaTable);
					}
				}
				#endregion
			}
		}

		#endregion

		#region 向上提供检测结果

		// 获取检测到的分控列表（暂不区分 U/D 口）
		public List<SubControlInfo> getSubControlInfoList()
		{
			List<SubControlInfo> subInfoList = new List<SubControlInfo>();
			
			for (int k = 0; k < subControlInfoList_U.Count; k++)
			{
				subInfoList.Add(subControlInfoList_U[k].clone());
			}
			for (int k = 0; k < subControlInfoList_D.Count; k++)
			{
				subInfoList.Add(subControlInfoList_D[k].clone());
			}

			return subInfoList;
		}

		// 获取检测到的附属设备列表（暂不区分 U/D 口）
		public List<EquipmentInfo> getEquControlInfoList()
		{
			List<EquipmentInfo> equInfoList = new List<EquipmentInfo>();

			if (equipmentInfoList_U.Count > 0)
			{
				for (int k = 0; k < equipmentInfoList_U.Count; k++)
				{
					equInfoList.Add(equipmentInfoList_U[k].clone());
				}
			}
			else
			{
				for (int k = 0; k < equipmentInfoList_D.Count; k++)
				{
					equInfoList.Add(equipmentInfoList_D[k].clone());
				}
			}

			return equInfoList;
		}

		#endregion

		// 创建亮度、对比度设置包负载数据
		private byte[] buildBrightContrastPacket(int brightness, int contrast, int temperature_r, int temperature_g, int temperature_b)
		{
			byte[] MemData = new byte[512];
			for (int i = 0; i < 512; i++)
			{
				MemData[i] = 0;
			}

			MemData[3] = mod256(contrast);
			MemData[4] = mod256(brightness);
			MemData[5] = mod256(temperature_r);
			MemData[6] = mod256(temperature_g);
			MemData[7] = mod256(temperature_b);

			return MemData;
		}

		// 发送亮度、对比度设置包
		private void sendBrightConfigPacket(int brightness, int contrast, int temperature_r, int temperature_g, int temperature_b)
		{
			byte[] configData = buildBrightContrastPacket(brightness, contrast, temperature_r, temperature_g, temperature_b);

			if (comPort != null)
			{
				writeSubMem(comPort, 0, 0, 0x0200, configData);	// 全局操作所有分控
			}
		}

		// 打印日志
		private new void typeLog(string str)
		{
			if (enableTypeLog)
			{
				base.typeLog(str);
			}
		}
	}
}
